import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns


# if __name__ == '__main__':
#     # 读取xls（绝对路径）
#     data = pd.read_excel(io='../data/sepisi_no_time.xlsx')
#     # 获取目标列
#     target = data['结局']
#     # 训练集合
#     training = data[data.columns.difference(['结局'])]
#     # 构造pca工具类
#     PCA = LoadPCA(training).startPCA()
#     # # 获得数据
#     data = PCA.transform(training)
#     # 二维图
#     # fig = plt.figure()
#     for i in range(0, len(data)):
#         if target[i] == 1:
#             plt.scatter(data[i][0], data[i][1], c='r', marker='*')
#         else:
#             plt.scatter(data[i][0], data[i][1], c='b', marker='o')
#     plt.show()


def meanX(dataX):
    """
    求均值
    axis=0表示依照列来求均值。假设输入list,则axis=1
    """
    return np.mean(dataX, axis=0)


if __name__ == '__main__':
    # 读取xls（
    data = pd.read_excel(io='../dataset/sepisi_no_time.xlsx')
    # 获取目标列
    target = data['结局']
    # 训练集合
    training = data[data.columns.difference(['结局'])]
    # 求均值
    average = meanX(training)
    # 查看列数和行数
    m, n = np.shape(training)
    # 均值矩阵
    data_adjust = []
    avgs = np.tile(average, (m, 1))
    # print(avgs)
    # 去中心化
    data_adjust = training - avgs
    # print(data_adjust)
    # 计算协方差矩阵
    covX = np.cov(data_adjust.T)
    # print(covX)
    # 计算协方差阵的特征值和特征向量
    # 求解协方差矩阵的特征值和特征向量
    featValue, featVec = np.linalg.eig(covX)
    # print(featValue, featVec)
    # 对特征值进行排序并输出 降序
    featValue = sorted(featValue)[::-1]

    # print(featValue)

    # 绘制散点图和折线图
    # 同样的数据绘制散点图和折线图
    plt.scatter(range(1, training.shape[1] + 1), featValue)
    plt.plot(range(1, training.shape[1] + 1), featValue)
    # 显示图的标题和xy轴的名字
    plt.title("Scree Plot")
    plt.xlabel("Factors")
    plt.ylabel("Eigenvalue")

    plt.grid()  # 显示网格
    plt.show()  # 显示图形

    # 求特征值的贡献度
    gx = featValue / np.sum(featValue)
    # print("特征值的贡献度按顺序为：")
    # print(gx)
    # 求特征值的累计贡献度
    lg = np.cumsum(gx)
    # print("特征值的累计贡献度按顺序为：")
    # print(lg)

    # 选出主成分
    k = [i for i in range(len(lg)) if lg[i] < 0.85]
    k = list(k)
    print("主要特征：")
    print(k)
    # 选出主成分对应的特征向量矩阵
    selectVec = np.matrix(featVec.T[k]).T
    # selectVe = selectVec * (-1)
    # print("选出主成分对应的特征向量矩阵：")
    # print(selectVec)
    # 主成分得分
    finalData = np.dot(data_adjust, selectVec)
    print(finalData)
    # 绘制热力图

    plt.figure(figsize=(14, 14))
    ax = sns.heatmap(selectVec, annot=True, cmap="BuPu")
    # 设置y轴字体大小
    ax.yaxis.set_tick_params(labelsize=15)
    plt.title("Factor Analysis", fontsize="xx-large")

    # 设置y轴标签
    plt.ylabel("Sepal Width", fontsize="xx-large")
    # 显示图片
    plt.show()

